<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="some_element"></div>
  <script>
    //引用计数
    function problem(){
      let objectA = new Object();
      let objectB = new Object();
      objectA.someOtherObject = objectB;
      objectB.anotherObject = objectA;
    }
    // objectA和objectB引用数永远为2,引用计数在对象互相引用时会导致内存永不释放.
    let element = document.getElementById("some_element");
    let myObject = new Object();
    myObject.element = element;
    element.someObject = myObject;
    //DOM对象和原生JS对象会相互引用,设为null可以切断变量与引用值的关系.
    myObject.element = null;
    element.someObject = null;

    function createPerson(name){
      let localPerson = new Object();
      localPerson.name = name;
      return localPerson;
    }
    let globalPerson = createPerson("Sloan");
    // 解除globalPerson对值的引用,要确保相关的值已经不在上下文里了.
    globalPerson = null;
    // 共享隐藏类
    // 避免"先创建再补充"(ready-fire-aim)的动态属性赋值,
    //在构造函数中一次性声明所有属性.
    function Article(opt_author){
      this.title = "A title";
      this.author = opt_author;
    }
    let a1 = new Article();
    let a2 = new Article('Jake');
    //最好是把不想要的属性设置为null
    a2.author = null;
    //内存泄漏一:意外声明全局变量
    function setName(){
      name = "Jake";
    }
    //二: 定时器的闭包回调
    // 定时器内部的回调要引用外部变量,会导致外部变量name不会被清除.
    // let name = "Sloan";
    // setInterval(() => {
    //   console.log(name);
    // },3000)

    //闭包造成的内存泄漏
    let outer = function(){
      let name = "Jake";
      return function(){
        return name;
      };
    };
    //静态分配与对象池

    /*
    调用这个函数,每次都会创建新的对象,当函数被频繁调用时,垃圾回收程序会发现这里对象更替速度会很快,
    从而频繁安排垃圾回收.
    */
    function addVector(a,b){
      let resultant = new Vector();
      resultant.x = a.x + b.x;
      resultant.y = a.y + b.y;
      return resultant;
    }

    /*
    不要动态创建矢量对象,让它使用已有的矢量对象
    */
   function addVector1(a,b,resultant){
    resultant.x = a.x + b.x;
    resultant.y = a.y + b.y;
    return resultant;
   }
   //对象池:vectorPool是已有的对象池
   //对象池用来管理一组可回收的对象,可以向对象池请求对象,设置属性并使用它,操作完成后再还给
   //对象池,过程没有对象初始化,垃圾回收程序也就不会频繁的运行.
   let v1 = vectorPool.allocate();
   let v2 = vectorPool.allocate();
   let v3 = vectorPool.allocate();

   v1.x = 10;
   v1.y = 5;
   v2.x = -3;
   v2.y = -6;

   addVector(v1,v2,v3);
   console.log([v3.x,v3.y]);

   vectorPool.free(v1);
   vectorPool.free(v2);
   vectorPool.free(v3);

   v1 = null;
   v2 = null;
   v3 = null;
  </script>
</body>
</html>